<template>
  <a-card>
    <a-space class="operator">
      <a-button type="primary" @click="showModal">新建</a-button>
    </a-space>
    <a-table :columns="columns" :data-source="data" :pagination="false" class="components-table-demo-nested"
             row-key="id">
      <a-table
          :columns="columns"
          :data-source="data"
          :row-selection="rowSelection"
          :expanded-row-keys.sync="expandedRowKeys"
      />
      <template slot="action" slot-scope="text,record,index">
        <a style="margin-right: 8px" @click="editPerm(record,index)">
          <a-icon type="edit"/>
          编辑</a>
        <a style="margin-right: 8px" @click="lockPerm(record)">
          <a-icon type="delete"/>
          {{ record.status === 'NORMAL' ? "锁定" : "解锁" }}</a>
      </template>
    </a-table>
    <a-modal v-model="visible" title="新增/编辑" on-ok="handleOk">
      <template slot="footer">
        <a-button key="back" @click="handleCancel">取消</a-button>
        <a-button key="submit" type="primary" @click="handleOk">保存</a-button>
      </template>
      <a-form-model
          ref="ruleForm"
          :model="form"
          :rules="rules"
          :label-col="{span: 7}"
          :wrapper-col="{span: 10}"
      >
        <a-form-model-item label="权限类型" prop="type" :labelCol="{span: 7}" :wrapperCol="{span: 30}">
          <a-radio-group v-model="form.type">
            <a-radio value="CATALOG">目录</a-radio>
            <a-radio value="MENU">菜单</a-radio>
            <a-radio value="BUTTON">按钮</a-radio>
          </a-radio-group>
        </a-form-model-item>

        <a-form-model-item label="权限名" ref="name" prop="name" :labelCol="{span: 7}" :wrapperCol="{span: 10}">
          <a-input v-model="form.name"
                   placeholder="请输入权限名"
                   @blur="() => {$refs.name.onFieldBlur();}"/>
        </a-form-model-item>

        <a-form-model-item label="权限别名" ref="alias" prop="alias" :labelCol="{span: 7}" :wrapperCol="{span: 10}">
          <a-input v-model="form.alias"
                   placeholder="请输入权限别名"
                   @blur="() => {$refs.alias.onFieldBlur();}"/>
        </a-form-model-item>

        <a-form-model-item label="权限编码" ref="code" prop="code" :labelCol="{span: 7}" :wrapperCol="{span: 10}">
          <a-input v-model="form.code"
                   placeholder="请输入权限编码"
                   @blur="() => {$refs.code.onFieldBlur();}"/>
        </a-form-model-item>

        <a-form-model-item label="权限路由" ref="router" prop="router" :labelCol="{span: 7}" :wrapperCol="{span: 10}">
          <a-input v-model="form.router"
                   placeholder="请输入权限路由"
                   @blur="() => {$refs.router.onFieldBlur();}"/>
        </a-form-model-item>

        <a-form-model-item label="图标" prop="icon" :labelCol="{span: 7}" :wrapperCol="{span: 10}">
          <a-input v-model="form.icon"
                   placeholder="请输入图标"/>
        </a-form-model-item>

        <a-form-model-item label="排序值" prop="sort" :labelCol="{span: 7}" :wrapperCol="{span: 10}">
          <a-input v-model="form.sort"
                   placeholder="请输入排序值"/>
        </a-form-model-item>

        <a-form-model-item label="关联资源" prop="resources" :labelCol="{span: 7}" :wrapperCol="{span: 10}"
                           v-if="form.type === 'MENU' || form.type === 'BUTTON'">
          <a-select v-model="form.resources" :filter-option="false" :not-found-content="fetching ? undefined : null"
                    :value="form.resources" mode="multiple" placeholder="请选择关联资源"
                    @change="handleChange" @search="loadResources">
            <a-spin v-if="fetching" slot="notFoundContent" size="small"/>
            <a-select-option v-for="res in resources" :key="res.code" :value="res.code">
              {{ res.name }}({{ res.url }})
            </a-select-option>
          </a-select>
        </a-form-model-item>
      </a-form-model>
    </a-modal>
  </a-card>
</template>
<script>
import {GET_PERMISSION, LOCK_PERMISSION, CREATE_PERMISSION, GET_RESOURCE, DETAIL_PERMISSION} from "@/services/api";
import {METHOD, request} from '@/utils/request'
import debounce from 'lodash/debounce';

const columns = [
  {
    title: '权限名',
    dataIndex: 'name',
    key: 'name',
    width: '30%',
  },
  {
    title: '编码',
    dataIndex: 'code',
    key: 'code'
  },
  {
    title: '路由',
    dataIndex: 'router',
    key: 'router',
  },
  {
    title: '类型',
    dataIndex: 'typeDisplayName',
    key: 'type',
  },
  {
    title: '状态',
    dataIndex: 'statusDisplayName',
    key: 'status',
  },
  {
    title: '更新时间',
    dataIndex: 'updateTime',
    key: 'updateTime',
  },
  {
    title: '操作',
    dataIndex: 'action',
    key: 'action',
    scopedSlots: {customRender: 'action'}
  }
];

const data = []

const rowSelection = {
  onChange: (selectedRowKeys, selectedRows) => {
    console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows);
  },
  onSelect: (record, selected, selectedRows) => {
    console.log(record, selected, selectedRows);
  },
  onSelectAll: (selected, selectedRows, changeRows) => {
    console.log(selected, selectedRows, changeRows);
  },
};

export default {
  data() {
    this.lastFetchId = 0;
    this.loadResources = debounce(this.loadResources, 800);
    return {
      data,
      columns,
      rowSelection,
      expandedRowKeys: [],
      visible: false,
      form: {
        name: '',
        code: '',
        alias: '',
        router: '',
        type: 'MENU',
        icon: '',
        sort: '1',
        resources: [],
      },
      rules: {
        name: [
          {type: 'string', required: true, message: '请填写权限名', trigger: 'blur'},
          {min: 1, max: 32, message: '权限名不能超过32个字', trigger: 'blur'},
        ],
        alias: [
          {type: 'string', required: true, message: '请填写权限别名', trigger: 'blur'},
          {min: 1, max: 64, message: '权限别名不能超过64个字', trigger: 'blur'},
        ],
        code: [
          {type: 'string', required: true, message: '请填写权限编码', trigger: 'blur'},
          {min: 1, max: 64, message: '权限编码不能超过64个字', trigger: 'blur'},
        ],
        router: [
          {type: 'string', required: true, message: '请填写权限路由', trigger: 'blur'},
          {min: 1, max: 64, message: '权限路由不能超过64个字', trigger: 'blur'},
        ],
        type: [
          {type: 'string', required: true, message: '请选择权限类型', trigger: 'change'}
        ],
        resources: [
          {type: 'array', required: true, message: '请选择关联资源', trigger: 'change'}
        ]
      },
      resources: [],
      fetching: false
    };
  },
  created() {
    this.loadData();
  },
  methods: {
    loadData() {
      request(GET_PERMISSION, METHOD.POST, {}).then(result => {
        if (result.data.code === "SUCCESS") {
          this.data = new Array();
          const respData = result.data.data;
          respData.forEach(item => {
            this.data.push(item);
          });
          console.log(this.data);
        } else {
          this.$message.success(result.data.msg, 3)
        }
      })
    },
    lockPerm(rowData) {
      console.log(rowData);
      const options = {
        id: rowData.id,
        status: rowData.status === 'NORMAL' ? "LOCKED" : "NORMAL"
      }
      request(LOCK_PERMISSION, METHOD.POST, options).then(result => {
        if (result.data.code === "SUCCESS") {
          if (rowData.status === 'NORMAL') {
            rowData.status = 'LOCKED';
            this.$message.success("锁定成功", 3);
          } else {
            rowData.status = 'NORMAL';
            this.$message.success("解锁成功", 3);
          }
        } else {
          this.$message.error(result.data.msg, 5)
        }
      })
    },
    editPerm(rowData) {
      this.showModal();
      request(DETAIL_PERMISSION + "?id=" + rowData.id, METHOD.GET).then(result => {
        if (result.data.code === "SUCCESS") {
          const editData = result.data.data;
          const resData = [];
          const resOption = [];
          editData.resources.forEach(res => {
            resData.push(res.code);
            resOption.push({
              code: res.code,
              name: res.name,
              url: res.url
            })
          })
          editData.resources = resData;
          this.form = editData;
          this.resources = resOption;
          console.log(this.form)
        } else {
          this.$message.error(result.data.msg, 5)
        }
      })
    },
    showModal() {
      this.visible = true;
      this.$nextTick(() => {
        this.$refs.ruleForm.resetFields();
      })
    },
    handleOk() {
      console.log('form ->value')
      console.log(this.form);
      this.$refs.ruleForm.validate(valid => {
        if (valid) {
          console.log(this.form);

          const options = this.form;
          console.log('options')
          console.log(options)
          request(CREATE_PERMISSION, METHOD.POST, options).then(result => {
            if (result.data.code === "SUCCESS") {
              this.$message.success("保存成功", 5)
              this.visible = false;
              this.loadData();
            } else {
              this.$message.error(result.data.msg, 5)
            }
          })
        } else {
          console.log('error submit!!');
          return false;
        }
      });
    },
    handleCancel() {
      this.visible = false;
    },
    loadResources(value) {
      this.lastFetchId += 1;
      const fetchId = this.lastFetchId;
      this.resources = [];
      this.fetching = true;

      const options = {
        page: 1,
        size: 10,
        condition: {
          name: value,
          url: value
        }
      }
      request(GET_RESOURCE, METHOD.POST, options).then(result => {
        if (result.data.code === "SUCCESS") {
          if (fetchId !== this.lastFetchId) {
            // for fetch callback order
            return;
          }
          const respData = result.data.data;
          const resData = respData.records.map(res => ({
            code: `${res.code}`,
            name: `${res.name}`,
            url: `${res.url}`
          }));
          this.resources = resData;
          this.fetching = false
        } else {
          this.$message.error(result.data.msg, 5)
        }
      })
    },
    handleChange(value) {
      Object.assign(this, {
        value,
        data: [],
        fetching: false,
      });
    }
  }
};
</script>

<style lang="less" scoped>
.operator {
  margin-bottom: 18px;
}
</style>
